////////////////////////////
/** \file CFunctionality.h
 *	OzZ Controls Functionality 
 *	Include this directly for a interface-plugin-project!\n
 *	Include OzZcontrols.h to your application-project instead.\n
 *	This file contains the functions provided by OzZControls for an interface.
 *	Use only this class in an Interface!
 *	(c) Copyright by Daniel Bulla 2006
 *	\author Daniel 'OzZ' Bulla
 */
#pragma once

#ifdef PLUGIN_EXPORT
#define PLUGIN_API __declspec(dllexport)
#else
#define PLUGIN_API __declspec(dllimport)
#endif

namespace oc
{

class OzZCore;

class PLUGIN_API CFunctionality
{
	friend OzZCore;
	CFunctionality();
	~CFunctionality();
public:
// ---
	void SimulateHookCall(const Element* const pTo, HOOKID hook);		///< Can be called by Plugin to simulate a hook-call
	void EnableHook(const Element* const pFor, HOOKID hook);			///< Makes a Hook (eg. "OnMouseOver") being invoked on the event
	void DisableHook(const Element* const pFor, HOOKID hook);			///< Disables a Hook again; By default every Hook is disabled, excepting "Init"

	void PopParameter(PARAMETER* pParam);								///< Plugin takes a parameter;
																		/**< You have to know about the type of an Parameter on your own!
																		 *	 It gets you a parameter from the stack and decreases the
																		 *	 stack-pointer. That means another call to this function will
																		 *	 give you the next Parameter. If there is no parameter anymore
																		 *	 the behaviour of the function is undefined, take care about
																		 *	 the parameters a certain hook provides on your own!
																		 *	 \param pParam blank PARAMETER to fill data in
																		 *	 \return the parameter is returned in #var pParam
																		 */
	void PushParameter(void* pParam);									///< Only needed for simulation of Hook Calls by the interface
	// -Functional-Functions

		/// Allocates a new Element and initializes it.
		/** \param bFocus Indicates if the Element should get focus on startup?
		 *	\param pData Holds information about the Element. A Copy of the provided Paper is used.
		 */
	Element*		AddElement(Element* pParent) const;
	void			DeleteElement(Element* pElem) const;
	void			FocusElement(const Element* const) const;	///< Focuses an Element. \return false if it was already focused
	Element*		GetFocusedElement() const;					///< \return The Element that has the Focus on requestion time.
		/// Updates a parameter of an Element.
		/** One of the most important Functions. It is used to
		 *	affect Elements during execution. \todo provide a GetElementPaper Function for faster updating
		 *  You have to know about the type of the member you
		 *	are beeing to set.
		 *	\param pElem The Element to update the parameter of.
		 *	\param oMember Offset-pointer, identifying the member about to be set. (an ElementPaper-Member Pointer)
		 *	\param pValue The value to set. Keep track of the right type on your own! (according to \todo link ElementPaper-Member Pointers)
		 *	\sa ElementPaper-Member Pointer
		 */
	void			SetElementMember(		Element* const	pElem, void* ElementPaper::* pMember, void* pValue) const;
		/// Use this to keep track of the Element's parameter. \sa SetElementMember
	void*			GetElementMember(const	Element* const	pElem, void* ElementPaper::* pMember) const;

		/// Gives information about the position of points.
		/** Usefull for testing over which element the mouse, the middle of the screen or any other point is.
		 *	\return the toppest Element under the Point(s), #var AdvancedCollisionInfo holds more information;
		 *	The Check beginns at the position in tree, as if pElem was the "Desktop"
		 *	\param papResults the result of the test is saved here \todo how to clean up papResults? Array is provided (beacuse of pointSSSS = plural)!
		 *	\sa For testing if points are over a specified Element use PointsOver.
		 */
	Element*		PointsOverWhich(AdvancedCollisionInfo** papResults, const Coord2D_si* const paPoints, const UINT uiNoOfPoints, const Element* const pElem =NULL);
		/// Gives information about points in view of an Element. \todo how to clean up paResults
	void			PointsOver(CollisionInfo* const paResults, Coord2D_si* const paPoints, const UINT uiNoOfPoints, const Element* const pElem, bool bCheckChildren) const;

//	Coord2D_si		Coord2DexTosi(const Element* const = NULL, const Coord2D_ex* const);
		/// Converts between the coordinate-systems of different Elements.
	void			TransformPoints(Coord2D_si* const paResults, const Coord2D_si* const paPoints, const unsigned int uiNoOfPoints, const Element* const pFrom, const Element* const pTo) const;
};

} //namespace oc

extern "C"
{
PLUGIN_API void* GetData(void);
PLUGIN_API void FreeData(void);
}